//
//  setup_mcast.cpp
// ~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2013-2014 Razvan Coca (razvan dot coca at  gmail dot com)
// 
//


#include "setup_mcast.hpp"
#include "logging/logging.hpp"

void setup_mcast_socket(
        boost::asio::ip::udp::socket& msocket,
        boost::asio::ip::udp::endpoint const& local_if,
        boost::asio::ip::udp::endpoint const& mcast_group,
        int ttl,bool reuse,bool loopback)
{
    try{
        DLOG(INFO)<<"multicast group:"<<mcast_group;
        DLOG(INFO)<<"local interface:"<<local_if;
        if(!msocket.is_open())
            msocket.open(local_if.protocol());
        if(reuse)
            msocket.set_option(boost::asio::ip::udp::socket::reuse_address(true));
        if(loopback)
            msocket.set_option(boost::asio::ip::multicast::enable_loopback(true));
        else
            msocket.set_option(boost::asio::ip::multicast::enable_loopback(false));
        msocket.set_option(boost::asio::ip::multicast::hops(ttl));

        msocket.set_option(boost::asio::ip::multicast::outbound_interface(local_if.address().to_v4()));
        boost::asio::ip::udp::endpoint local_listener(local_if.address(),mcast_group.port());
        msocket.bind(local_listener);
        msocket.set_option(boost::asio::ip::multicast::join_group(mcast_group.address().to_v4(),local_if.address().to_v4()));


    }
    catch(std::exception const &e)
    {
        LOG(ERROR)<<__FUNCTION__<<" error:"<<e.what();
        throw;
    }
}

void teardown_mcast_socket(boost::asio::ip::udp::socket& msocket,
                           boost::asio::ip::udp::endpoint const& mcast_group)
{
    msocket.set_option(boost::asio::ip::multicast::leave_group(mcast_group.address().to_v4()));
}
